import {
	BLE_ERR,
	YOUON_LOCK_CONF
} from './constants.js'
import util from './util.js'
export default class BaseBle {
	/**
	 * deviceId 设备名称	 
	 */
	constructor(options = {
		serviceUUID: YOUON_LOCK_CONF.SERVICE_UUID,
		writeUUID: YOUON_LOCK_CONF.WRITE_UUID,
		notifyUUID: YOUON_LOCK_CONF.NOTIFY_UUID,
		searchTimeout: YOUON_LOCK_CONF.SEARCH_TIMEOUT, // 搜索超时时间
		mtuSize: YOUON_LOCK_CONF.MTU_SIZE, // mtu大小 单位字节
	}) {
		const {
			serviceUUID,
			writeUUID,
			notifyUUID,
			searchTimeout,
			mtuSize
		} = options;
		this.serviceUUID = serviceUUID;
		this.writeUUID = writeUUID;
		this.notifyUUID = notifyUUID;
		this.searchTimeout = searchTimeout;
		this.mtuSize = mtuSize;
	}

	// 授权小程序使用定位服务
	doAuthorize(scopeStr = 'scope.userLocation') {
		console.log('scopeStr--->', scopeStr)
		return new Promise((resolve, reject) => {
			uni.authorize({
				scope: scopeStr,
				success: () => {
					console.log('doAuthorize success')
					resolve();
				},
				fail: (res) => {
					console.log('doAuthorize err-->', res)
					reject({
						code: BLE_ERR.NO_LOCATION_AUTH,
						msg: BLE_ERR.NO_LOCATION_AUTH_MSG
					})
				}
			})
		})
	}

	// 打开蓝牙设备器
	openBluetoothAdapter() {
		return new Promise((resolve, reject) => {
			uni.openBluetoothAdapter({
				mode: 'central',
				success: () => {
					resolve();
				},
				fail: (res) => {
					reject({
						code: BLE_ERR.OPEN_ADAPTER_FAIL,
						msg: BLE_ERR.OPEN_ADAPTER_FAIL_MSG
					})
				}
			})
		})
	}

	// 获取蓝牙适配器状态
	getBluetoothAdapterState() {
		return new Promise((resolve, reject) => {
			uni.getBluetoothAdapterState({
				success: (res) => {
					resolve(res)
				},
				fail: (res) => {
					reject({
						code: BLE_ERR.ADAPTER_STATE_FAIL,
						msg: BLE_ERR.ADAPTER_STATE_FAIL_MSG
					})
				}
			})
		})
	}
	/**
	 * startDiscovery 搜索蓝牙设备
	 * bleName 蓝牙设备名称 一般是蓝牙MAC 如果该参数有值 那么 就不会执行回调函数	 
	 * findDevFunc 发现设备的回调函数
	 */
	startDiscoveryPromise(bleName = '') {
		return new Promise((resolve, reject) => {
			// 先监听
			uni.onBluetoothDeviceFound((res) => {
				const device = res.devices[0];
				// console.log('发现设备-->', device)
				if (!device.name && !device.localName) {
					return;
				}
				if (device.deviceId == bleName) {
					console.log('发现设备-->', device)
					if (this.searchTimer) clearTimeout(this.searchTimer);
					this.stopBluetoothDevicesDiscovery()
					resolve(device)
				}
			})
			// 然后开启搜索
			uni.startBluetoothDevicesDiscovery({
				allowDuplicatesKey: false,
				success: () => {
					console.log('开始搜索...');
					this.searchTimer = setTimeout(() => {
						if (this.searchTimer) clearTimeout(this.searchTimer);
						this.stopBluetoothDevicesDiscovery();
						console.log('超时结束搜索...')
						reject({
							code: BLE_ERR.SEARCH_TIME_OUT_FAIL,
							msg: BLE_ERR.SEARCH_TIME_OUT_FAIL_MSG
						})
					}, this.searchTimeout)
				},
				fail: (res) => {
					reject({
						code: BLE_ERR.START_DISCOVERY_FAIL,
						msg: BLE_ERR.START_DISCOVERY_FAIL_MSG
					})
				}
			})
		})
	}
	/**
	 * 回调函数模式的搜索 超时需要自己在子类中调用
	 */
	startDiscoveryCallBack(findDevFunc = null) {
		uni.onBluetoothDeviceFound((res) => {
			const device = res.devices[0];
			// console.log('发现设备-->', device)
			if (!device.name && !device.localName) {
				return;
			}
			if (findDevFunc) findDevFunc(device)
		})
		// 然后开启搜索
		uni.startBluetoothDevicesDiscovery({
			allowDuplicatesKey: false,
			success: () => {
				console.log('开始搜索...')
			},
			fail: (res) => {
				reject({
					code: BLE_ERR.START_DISCOVERY_FAIL,
					msg: BLE_ERR.START_DISCOVERY_FAIL_MSG
				})
			}
		})
	}

	// 创建连接
	createBLEConnection(deviceId) {
		if (!deviceId) throw new Error({
			code: BLE_ERR.NO_DEVICE_ID_MSG,
			msg: BLE_ERR.NO_DEVICE_ID_MSG
		})
		return new Promise((resolve, reject) => {
			uni.createBLEConnection({
				deviceId,
				timeout: 6000, // 连接超时时间 ms
				success: () => {
					console.log('蓝牙连接成功')
					this.connDeviceId = deviceId;
					resolve();
				},
				fail: (res) => {
					console.log('createBLEConnection err--->', res)
					reject({
						code: BLE_ERR.CONN_FAIL,
						msg: BLE_ERR.CONN_FAIL_MSG
					})
				}
			})
		})
	}

	/**
	 * @param {Object} size 字节数
	 * 修改成功就使用修改的字节数 修改失败 则使用默认字节数20
	 */
	setBLEMTU(size = this.mtuSize) {
		return new Promise((resolve, reject) => {
			uni.setBLEMTU({
				deviceId: this.connDeviceId,
				mtu: size, // 120个字节
				success: () => {
					this.mtuSize = size;
					console.log('设置mtu成功,', size);
					resolve();
				},
				fail: (res) => {
					console.log('设置mtu失败,', this.mtuSize);
					resolve(this.mtuSize);
				}
			})
		})
	}

	// 获取连接的蓝牙设备的所有服务
	getBLEDeviceServices() {
		return new Promise((resolve, reject) => {
			uni.getBLEDeviceServices({
				deviceId: this.connDeviceId,
				success: (res) => {
					const services = res.services;
					resolve(services)
				},
				fail: (res) => {
					console.log('getBLEDeviceServices err', res)
					reject({
						code: BLE_ERR.GET_SERVICES_FAIL,
						msg: BLE_ERR.GET_SERVICES_FAIL_MSG
					})
				}
			})
		})
	}
	// 获取蓝牙设备特征值
	getBLEDeviceCharacteristics() {
		return new Promise((resolve, reject) => {
			uni.getBLEDeviceCharacteristics({
				deviceId: this.connDeviceId,
				serviceId: this.serviceUUID,
				success: (res) => {
					resolve(res.characteristics);
				},
				fail: (res) => {
					reject({
						code: BLE_ERR.GET_CHARACTER_FAIL,
						msg: BLE_ERR.GET_CHARACTER_FAIL_MSG
					})
				}
			})
		})
	}

	// 启用特征值变化监听
	notifyBLECharacteristicValueChange() {
		console.log('connDeviceId->', this.connDeviceId);
		console.log('serviceUUID->', this.serviceUUID);
		console.log('notifyUUID->', this.notifyUUID);
		return new Promise((resolve, reject) => {
			uni.notifyBLECharacteristicValueChange({
				deviceId: this.connDeviceId,
				serviceId: this.serviceUUID,
				characteristicId: this.notifyUUID,
				state: true,
				success: (res) => {
					console.log('监听特征值成功...')
					resolve();
				},
				fail: (res) => {
					reject({
						code: BLE_ERR.NOTIFY_CHARACTER_FAIL,
						msg: BLE_ERR.NOTIFY_CHARACTER_FAIL_MSG
					})
				}
			})
		})
	}

	// 向蓝牙设备写入数据	
	writeBLECharacteristicValue(data) {
		return new Promise((resolve, reject) => {
			uni.writeBLECharacteristicValue({
				deviceId: this.connDeviceId,
				serviceId: this.serviceUUID,
				characteristicId: this.writeUUID,
				value: data,
				success: () => {
					resolve();
				},
				fail: (res) => {
					reject({
						code: BLE_ERR.WRITE_DATA_FAIL,
						msg: BLE_ERR.WRITE_DATA_FAIL_MSG
					})
				}
			})
		})
	}

	// 向control pointer中写入数据 
	writeTo90001(data) {
		return new Promise((resolve, reject) => {
			uni.writeBLECharacteristicValue({
				deviceId: this.connDeviceId,
				serviceId: this.serviceUUID,
				characteristicId: this.notifyUUID,
				value: data,
				success: () => {
					resolve();
				},
				fail: (res) => {
					reject({
						code: BLE_ERR.WRITE_DATA_FAIL,
						msg: BLE_ERR.WRITE_DATA_FAIL_MSG
					})
				}
			})
		})
	}
	// 向packet 中写入数据
	writeTo90002(data) {
		return new Promise((resolve, reject) => {
			uni.writeBLECharacteristicValue({
				deviceId: this.connDeviceId,
				serviceId: this.serviceUUID,
				characteristicId: this.writeUUID,
				value: data,
				success: () => {
					resolve();
				},
				fail: (res) => {
					reject({
						code: BLE_ERR.WRITE_DATA_FAIL,
						msg: BLE_ERR.WRITE_DATA_FAIL_MSG
					})
				}
			})
		})
	}

	// 收到蓝牙返回的数据
	onBLECharacteristicValueChange(bleDataCallFunc = null) {
		uni.onBLECharacteristicValueChange((res) => {
			const str = util.ab2hex(res.value);
			if (bleDataCallFunc) bleDataCallFunc(str)
		})
	}

	// 停止扫描
	stopBluetoothDevicesDiscovery() {
		return new Promise((resolve, reject) => {
			uni.stopBluetoothDevicesDiscovery({
				success: () => {
					console.log('停止扫描...')
					resolve(true);
				},
				fail: (res) => {
					reject({
						code: BLE_ERR.STOP_DISCOVERY_FAIL,
						msg: BLE_ERR.STOP_DISCOVERY_FAIL_MSG
					})
				}
			})
		})
	}

	// 断开和蓝牙设备的连接
	closeBLEConnection() {
		return new Promise((resolve, reject) => {
			uni.closeBLEConnection({
				deviceId: this.connDeviceId,
				success: () => {
					resolve();
				},
				fail: (res) => {
					resolve({
						code: BLE_ERR.DIS_CONN_FAIL,
						msg: BLE_ERR.DIS_CONN_FAIL_MSG
					})
				}
			})
		})
	}

	// 关闭蓝牙适配器
	closeBluetoothAdapter() {
		return new Promise((resolve, reject) => {
			uni.closeBluetoothAdapter({
				success: () => {
					resolve();
				},
				fail: (res) => {
					reject({
						code: BLE_ERR.CLOSE_ADAPTER_FAIL,
						msg: BLE_ERR.CLOSE_ADAPTER_FAIL_MSG
					})
				}
			})
		})
	}

}